package com.qianxun.plugins.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 权限管理工具
 * @author: huwei
 * @date: 2019/10/22 19:41
 * @version: 1.0.0
 */
public class ShiroUtil {
    /**
     * 系统运行时，权限拦截缓存池：在运行状态下，添加拦截权限，使权限不可用
     */
    private static final Map<String ,Object> RUNTIME_INTERCEPT_PERMISSION_BUFFER = new ConcurrentHashMap<>();

    /**
     * 获取当前 Subject
     *
     * @return Subject
     */
    public static Subject getSubject() {
        return SecurityUtils.getSubject();
    }

    /**
     * 从shiro获取session
     */
    public static Session getSession() {
        return getSubject().getSession();
    }

    /**
     * 获取shiro指定的sessionKey
     */
    @SuppressWarnings("unchecked")
    public static <T> T getSessionAttr(String key) {
        Session session = getSession();
        return session != null ? (T) session.getAttribute(key) : null;
    }

    /**
     * 设置shiro指定的sessionKey
     */
    public static void setSessionAttr(String key, Object value) {
        Session session = getSession();
        session.setAttribute(key, value);
    }

    /**
     * 移除shiro指定的sessionKey
     */
    public static void removeSessionAttr(String key) {
        Session session = getSession();
        if (session != null) {
            session.removeAttribute(key);
        }
    }

    /**
     * 获取当前登录用户
     * @return
     */
    public static Object getUser(){
        return getSubject().getPrincipals() == null ? null : getSubject().getPrincipals().getPrimaryPrincipal();
    }

    /**
     * 获取当前登录用户
     * @param loginUserType 用户类型类对象
     * @param <T>
     * @return
     */
    public static <T> T getUser(Class<? extends T> loginUserType){
        Object loginUser = getUser();
        return loginUser != null && loginUserType.isAssignableFrom(loginUser.getClass()) ? (T)loginUser : null;
    }

    /**
     * 是否登录
     * @return
     */
    public static boolean isLogin(){
        return getUser() != null;
    }

    /**
     * 指定类型用户是否登录
     * @param loginUserType 用类型类对象
     * @param <T>
     * @return
     */
    public static <T> boolean isLogin(Class<? extends T> loginUserType){
        return getUser(loginUserType) != null;
    }

    /**
     * 判断当前用户是否具有指定权限
     * @param permission 权限标识，一般为url地址
     * @return
     */
    public static boolean hasPermission(String permission){
        return !RUNTIME_INTERCEPT_PERMISSION_BUFFER.containsKey(permission) && getSubject() != null && getSubject().isPermitted(permission);
    }

    /**
     * 添加全局的权限拦截，将作用于所有用户身上
     * @param permission 权限标识，一般为url地址
     */
    public static void addGlobalInterceptPermission(String permission){
        RUNTIME_INTERCEPT_PERMISSION_BUFFER.put(permission,null);
    }

    /**
     * 删除全局的权限拦截
     * @param permission 权限标识，一般为url地址
     */
    public static void removeGlobalInterceptPermission(String permission){
        RUNTIME_INTERCEPT_PERMISSION_BUFFER.remove(permission);
    }

}
